﻿using _22_JWT封装.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Reflection;
using System.Security.Claims;

namespace _22_JWT封装
{
    /// <summary>
    ///  验证版本号
    /// </summary>
    public class JWTVersionCheckFilter : IAsyncActionFilter
    {
        public readonly UserManager<MyUser> userManager;
        public JWTVersionCheckFilter(UserManager<MyUser> userManager) { 
            this.userManager = userManager;
        }
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {

            ControllerActionDescriptor? cad = context.ActionDescriptor as ControllerActionDescriptor;
            if (cad == null)
            {
                await next();
                return;
            }
            var b = cad.MethodInfo.GetCustomAttributes(typeof(JWTNotCheckAttribute)).Any();
            if (b)
            {
                await next();
                return;
            }

            var version= context.HttpContext.User.FindFirst("JWTVersion");
            if (version == null)
            {
                context.Result = new ObjectResult("没有jwtVerison") { StatusCode = 400 };
                return ;
            }
            else {
                long jwtVerFromClient=Convert.ToInt64(version.Value); // 客户端传来的版本
                var ClaimUserId = context.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier);
                long userId=Convert.ToInt64(ClaimUserId.Value); // 客户端传来的用户ID

                // 不用每次都要查询数据库 可以使用缓存
                var user = await userManager.FindByIdAsync(userId.ToString()); //查询数据库
                if (user == null)
                {
                    context.Result = new ObjectResult("查询不到该用户") { StatusCode = 400 };
                    return;
                }
                if (jwtVerFromClient < user.JWTVersion)
                {
                    context.Result = new ObjectResult("JWT过时") { StatusCode = 400 };
                    return;
                }
                await next();
            }


        }
    }
}
